package com.htl.exampro.gateway.filter;

import com.htl.exampro.gateway.pojo.GatewayLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

/**
 * 全局日志记录过滤器，用于记录所有经过网关的请求日志
 */
@Component
@Slf4j
public class GatewayLoggingFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        GatewayLog log = new GatewayLog();
        log.setRequestTime(new Date());
        log.setTraceId(exchange.getRequest().getHeaders().getFirst("X-Trace-ID"));
        log.setRequestPath(exchange.getRequest().getPath().value());
        log.setIp(exchange.getRequest().getRemoteAddress() != null ? exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() : "unknown");
        log.setRequestMethod(exchange.getRequest().getMethod().name());
        log.setSchema(exchange.getRequest().getURI().getScheme());

        // 记录请求头
        log.setRequestHeaders(exchange.getRequest().getHeaders().toString());

        return chain.filter(exchange).doOnSuccess(aVoid -> {
            log.setResponseTime(new Date());
            log.setExecuteTime(log.getResponseTime().getTime() - log.getRequestTime().getTime());
            log.setResponseHeaders(exchange.getResponse().getHeaders().toString());
            log.setCode(exchange.getResponse().getStatusCode().value());
            MediaType contentType = exchange.getResponse().getHeaders().getContentType();
            if (contentType != null) {
                log.setResponseContentType(contentType.getType());
            }
            Route attribute = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
            log.setTargetServer(attribute.getId());

            // 输出日志
            System.out.println("Gateway Log: " + log);
        }).doOnError(throwable -> {
            log.setResponseTime(new Date());
            log.setExecuteTime(log.getResponseTime().getTime() - log.getRequestTime().getTime());
            log.setCode(500);
            log.setResponseContentType("text/plain");
            log.setResponseHeaders("Error: " + throwable.getMessage());

            // 输出错误日志
            System.out.println("Gateway Error Log: {}" + log + throwable);
        });
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 10000;
    }
}